package com.plate.gateway.filter;

import com.plate.common.core.constants.RequestConstant;
import com.plate.common.core.constants.SysConstant;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.entity.ContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.rewrite.ModifyRequestBodyGatewayFilterFactory;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

import java.util.Map;

/**
 * @ClassName ModifyRequestGatewayFilterFactory
 * @Description TODO
 * @Author jiaxd
 * @Date 2023年10月30日 20:15
 * @Version 1.0
 */

@Slf4j
@Component
public class ModifyRequestGatewayFilterFactory extends AbstractGatewayFilterFactory<ModifyRequestGatewayFilterFactory.Config> {

    @Autowired
    private PasswordEncoder passwordEncoder;

    public ModifyRequestGatewayFilterFactory() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            ServerHttpRequest request = exchange.getRequest();
            String method = request.getMethodValue();
            String contentType = request.getHeaders().getFirst(RequestConstant.CONTENT_TYPE);

            // 对新增、修改用户密码时的密码进行加密
            if (contentType != null && HttpMethod.POST.name().equalsIgnoreCase(method) && contentType.contains(RequestConstant.CONTENT_TYPE_JSON)) {
                ModifyRequestBodyGatewayFilterFactory.Config requestBodyConfig = new ModifyRequestBodyGatewayFilterFactory.Config()
                        .setContentType(ContentType.APPLICATION_JSON.getMimeType())
                        .setRewriteFunction(Map.class, Map.class, (exchange1, originalRequestBody) -> {
                            if (originalRequestBody.containsKey(SysConstant.PASSWORD)) {
                                originalRequestBody.put(SysConstant.PASSWORD, passwordEncoder.encode(originalRequestBody.get(SysConstant.PASSWORD).toString()));
                            }
                            return Mono.just(originalRequestBody);
                        });
                return new ModifyRequestBodyGatewayFilterFactory().apply(requestBodyConfig).filter(exchange, chain);
            }

            return chain.filter(exchange);
        };
    }


    @Data
    public static class Config {

    }

    @Override
    public String name() {
        return "ModifyRequestGatewayFilterFactory";
    }

}
